<template>
  <div>
    <quill-editor ref="myQuillEditor" :value="text" class="my-ql-editor" @change="onChange" :options="editorOption" />
    <input style="display: none" ref="fileInput" type="file" name="file" multiple
      accept="image/jpg, image/jpeg, image/png, image/gif, image/webp" @change="upload" />

    <el-dialog title="源码模式" :visible.sync="isCode" append-to-body width="50%">
      <el-input type="textarea" :autosize="{ minRows: 5, maxRows: 20 }" placeholder="请输入内容" v-model="codeText">
      </el-input>
      <span slot="footer" class="dialog-footer">
        <el-button @click="isCode = false">取 消</el-button>
        <el-button type="primary" @click="
          isCode = false;
        text = codeText;
        ">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import editorOption from "./config";

export default {
  name: "RichText",
  props: ["value"],
  model: {
    prop: "value",
    event: "change",
  },
  data() {
    return {
      editorOption,
      text: this.value,
      isCode: false, // 是否开启源码模式
      codeText: "", // 用于源码模式的显示文本
    };
  },
  methods: {
    // 上传图片的api方法，返回图片的url
    async uploadApi(data) {
      let { image: url } = await this.$api.uploadImage(data);
      return url;
    },
    // 上传图片的处理逻辑
    async upload() {
      const _this = this;

      // 构造formData对象
      const files = Array.from(this.$refs.fileInput.files);

      files.forEach((file) => {
        const fd = new FormData();
        fd.append("image", file);

        // 调用上传文件接口
        _this
          .uploadApi(fd)
          .then((url) => {
            // 返回上传图片的地址
            let Range = _this.editor.getSelection();

            // 上传文件成功之后在富文本中回显(显示)
            _this.editor.insertEmbed(
              Range !== null ? Range.index : 0,
              "image",
              url
            );
            // 成功之后,将文件的文本框的value置空
            this.$refs.fileInput.value = "";
          })
          .catch((err) => {
            this.$refs.fileInput.value = "";
            console.log(err);
          });
      });
    },
    onChange(val) {
      this.$emit("change", val.html);
    },
  },
  computed: {
    editor() {
      return this.$refs.myQuillEditor.quill;
    },
  },
  mounted() {
    let _this = this;

    // 获取当前鼠标点击的坐标
    this.editor.container.addEventListener("click", function () {
      _this.selection = _this.editor.getSelection();
    });

    // 点击上传图片按钮的回调
    const imgHandler = function (image) {
      if (image) {
        const fileInput = _this.$refs.fileInput; // 隐藏的file文本ID
        fileInput.click(); // 加一个触发事件
      }
    };

    // 点击插入图片链接的按钮的回调
    const urlHandler = function (url) {
      if (url) {
        const href = prompt("请输入图像的链接");
        if (href) {
          let Range = _this.editor.getSelection();
          // 把获取的url链接插入到文本中
          _this.editor.insertEmbed(
            Range != null ? Range.index : 0,
            "image",
            href
          );
        }
      }
    };

    // 点击切换源码模式的按钮的回调
    const sourceEditorHandler = function (val) {
      if (val) {
        _this.isCode = val;
      }
    };

    // 在编辑器中添加对应的按钮
    this.editor.getModule("toolbar").addHandler("image", imgHandler);
    this.editor.getModule("toolbar").addHandler("link", urlHandler);
    this.editor
      .getModule("toolbar")
      .addHandler("sourceEditor", sourceEditorHandler);

    // 初始化按钮
    editorOption.initButton();
  },
  watch: {
    value(val) {
      this.text = val;
    },
    text: {
      immediate: true,
      handler(val) {
        this.codeText = val;
      },
    },
  },
};
</script>

<style src="./style.css">
</style>
